package com.org.devg.monitor.client.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class MonitorUtil {

    private final static Logger logger = LoggerFactory.getLogger(MonitorUtil.class);

    public final static String message = "message";

    public final static String horizontalSplit = "-";

    public final static String FORMAT_PATTERN1 = "yyyyMMddHHmmss";

    public final static String FORMAT_PATTERN3 = "yyyy-MM-dd HH:mm:ss";

    public final static String FORMAT_PATTERN4 = "yyyy-MM-dd";

    public static final String EARLY_SECOND = "00:00:00";

    public static final String LATE_SECOND = "23:59:59";

    public static final Pattern numberPattern = Pattern.compile("[0-9]*");


    public static String localDateTimeFormat(LocalDateTime localDateTime, String pattern) {
        return localDateTime.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String getStartTime() {
        return getNowDate(FORMAT_PATTERN3);
    }

    public static String getNowDate(String format) {
        return localDateTimeFormat(LocalDateTime.now(), format);
    }

    public static String getPreDate(String format) {
        return localDateTimeFormat(LocalDateTime.now().minusDays(1), format);
    }

    public static String getNextDate(String format) {
        return localDateTimeFormat(LocalDateTime.now().plusDays(1), format);
    }

    /**
     * 得到某个日期在这一天中时间最早的日期对象
     */
    public static String getEarlyInTheDay(LocalDate localDate) {
        return localDateFormat(localDate, FORMAT_PATTERN4) + " " + EARLY_SECOND;
    }

    /**
     * 得到某个日期在这一天中时间最晚的日期对象
     */
    public static String getLastInTheDay(LocalDate localDate) {
        return localDateFormat(localDate, FORMAT_PATTERN4) + " " + LATE_SECOND;
    }

    /**
     * 时间转化成 String 格式的时间
     *
     * @param dateFormat
     * @param millSec
     * @return
     */
    public static String transferLongToDate(String dateFormat, Long millSec) {
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        String millSecStr = millSec + "000";
        Date date = new Date(Long.valueOf(millSecStr));
        String resDate = sdf.format(date);
        return resDate;
    }

    /**
     * 判断是否为null或空字符串。如果不为null，在判断是否为空字符串之前会调用trim()。
     *
     * @param str
     * @return
     */
    public static boolean isNullOrEmpty(String str) {
        return str == null || str.trim().equals("");
    }

    /**
     * 判断是否为null或空字符串。如果不为null，在判断是否为空字符串之前会调用trim()。
     *
     * @param object
     * @return
     */
    public static boolean isNullOrEmpty(Object object) {

        if (object == null) {
            return true;
        }
        return isNullOrEmpty(object.toString());
    }

    public static String getMapString(Map<String, Object> map, String string) {
        return map == null ? null : map.get(string) == null ? null : String.valueOf(map.get(string));
    }

    public static Long getMapLong(Map<String, Object> map, String string) {
        String object = getMapString(map, string);
        return isNullOrEmpty(object) ? null : Long.parseLong(object);
    }

    public static boolean isNumeric(String str) {
        Matcher isNum = numberPattern.matcher(str);
        if (!isNum.matches()) {
            return false;
        }
        return true;
    }

    public static boolean equals(String str1, String str2) {
        return str1 == null ? str2 == null : str1.equals(str2);
    }

    public static long getTimestamp(String time, String format) {
        long timestamp = 0L;
        try {
            DateFormat df = new SimpleDateFormat(format);
            Date date = df.parse(time);
            Calendar cal = Calendar.getInstance();
            cal.setTime(date);
            timestamp = cal.getTimeInMillis();
        } catch (Exception ex) {
            logger.error("获取时间戳失败", ex);
        }
        return timestamp;
    }

    public static String localDateFormat(LocalDate localDate, String pattern) {
        return localDate.format(DateTimeFormatter.ofPattern(pattern));
    }

    public static String getCookieValue(HttpServletRequest request, String cookieName) {
        // TODO Auto-generated method stub
        String cookieValue = null;
        Cookie[] cookies = request.getCookies(); // 这样便可以获取一个cookie数组
        if (null != cookies && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                String coolieName = cookie.getName();
                if (null != coolieName && coolieName.equals(cookieName)) { // cookie存在登录成功
                    cookieValue = cookie.getValue();
                    break;
                }
            }
        }
        return cookieValue;
    }


    public static String getStackTraceMsg(Exception exception) {
        String msg = exception.getMessage();

        ByteArrayOutputStream stream = null;
        PrintStream ps = null;
        try {
            stream = new ByteArrayOutputStream();
            ps = new PrintStream(stream, true, "utf-8");
            exception.printStackTrace(ps);
            msg = stream.toString();
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    logger.error(e.getMessage());
                }
            }
            if (stream != null) {
                try {
                    stream.close();
                } catch (Exception e) {
                    logger.error(e.getMessage());
                }
            }
        }
        return msg;
    }

    public static String stringifyException(Throwable e) {
        StringWriter stm = new StringWriter();
        try {
            PrintWriter wrt = new PrintWriter(stm);
            e.printStackTrace(wrt);
            wrt.close();
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
        return stm.toString();
    }

}
